package cn.sc.summer.token.handler.gateway;

import cn.sc.summer.constant.model.Result;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.server.authorization.ServerAccessDeniedHandler;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.Charset;

/**
 * 网关访问拒绝异常处理
 */
@Slf4j
public class AccessDeniedHandlerX implements ServerAccessDeniedHandler {

    /**
     * 处理异常
     *
     * @param exchange 交换机
     * @param e        访问拒绝异常
     * @return Mono<Void>
     */
    @Override
    public Mono<Void> handle(ServerWebExchange exchange, AccessDeniedException e) {
        return Mono.defer(() ->
                Mono.just(exchange.getResponse())
        ).flatMap(response -> {
            response.setStatusCode(HttpStatus.FORBIDDEN);
            response.getHeaders().setContentType(MediaType.APPLICATION_JSON_UTF8);
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            DataBuffer buffer = dataBufferFactory.wrap(JSON.toJSONString(Result.fail(e.getMessage(), e.getMessage())).getBytes(Charset.defaultCharset()));
            return response.writeWith(Mono.just(buffer)).doOnError(error ->
                    DataBufferUtils.release(buffer)
            );
        });
    }
}
